class Solution:
    """
    比如：QWQRREQR

    count[ord('Q')] = 3、count[ord('W')] = 1、count[ord('R')] = 3、count[ord('E')] = 1
    need = 8 // 4 = 2、ans = 8

    第 1 次循环，left = right = 0
    因为 count[ord('Q')] > need，所以需要移动 right
    count[ord(s[right])] = count[ord(s[0])] = count[ord(Q)] -= 1，所以 count[ord(Q)] = 2
    right = right + 1 = 1

    第 2 次循环，left = 0 right = 1
    因为 count[ord('R')] > need，所以需要移动 right
    count[ord(s[right])] = count[ord(s[1])] = count[ord(W)] -= 1，所以 count[ord(W)] = 0
    right = right + 1 = 2

    第 3 次循环，left = 0 right = 2
    因为 count[ord('R')] > need，所以需要移动 right
    count[ord(s[right])] = count[ord(s[2])] = count[ord(Q)] -= 1，所以 count[ord(Q)] = 1
    right = right + 1 = 3

    第 4 次循环，left = 0 right = 3
    因为 count[ord('R')] > need，所以需要移动 right
    count[ord(s[right])] = count[ord(s[3])] = count[ord(R)] -= 1，所以 count[ord(R)] = 2
    right = right + 1 = 4

    第 5 次循环，left = 0 right = 4
    因为 count[ord('R')]、count[ord(W)]、count[ord(Q)]、count[ord(R)] 均小于 need，所以需要移动 left
    ans = min(ans, right - left) = min(8, 4 - 0) = 4
    count[ord(s[left])] = count[ord(s[0])] = count[ord(Q)] += 1，所以 count[ord(Q)] = 2
    left = left + 1 = 1

    第 6 次循环，left = 1 right = 4
    因为 count[ord('R')]、count[ord(W)]、count[ord(Q)]、count[ord(R)] 均小于 need，所以需要移动 left
    ans = min(ans, right - left) = min(4, 4 - 1) = 3
    count[ord(s[left])] = count[ord(s[1])] = count[ord(W)] += 1，所以 count[ord(W)] = 1
    left = left + 1 = 2

    第 7 次循环，left = 2 right = 4
    因为 count[ord('R')]、count[ord(W)]、count[ord(Q)]、count[ord(R)] 均小于 need，所以需要移动 left
    ans = min(ans, right - left) = min(3, 3 - 1) = 2
    count[ord(s[left])] = count[ord(s[2])] = count[ord(Q)] += 1，所以 count[ord(Q)] = 3
    left = left + 1 = 3

    第 7 次循环，left = 3 right = 4
    因为 count[ord('Q')] > need，所以需要移动 right
    ans = min(ans, right - left) = min(3, 3 - 1) = 2
    count[ord(s[left])] = count[ord(s[2])] = count[ord(Q)] += 1，所以 count[ord(Q)] = 3
    left = left + 1 = 3
    """
    def balancedString(self, s: str) -> int:
        """
        count 的作用：
        1. 首先用于统计整个字符串中所有字符的个数
        2. 然后用于维护滑动窗口外的字符的个数
        """
        count = [0] * 128
        for c in s:
            count[ord(c)] += 1
        need, ans = len(s) // 4, len(s)
        left, right = 0, 0
        while right <= len(s):
            """
            如果 count 中的字符的个数有一个大于 need 的话，则移动 right
            扩大窗口，减去 count 中相应字符出现的次数
            """
            if (count[ord('Q')] > need or
                    count[ord('W')] > need or
                    count[ord('E')] > need or
                    count[ord('R')] > need):
                if right >= len(s):
                    break
                # 滑动窗口内的字符的个数减一
                count[ord(s[right])] -= 1
                right += 1
                continue
            """
            缩小窗口，加上 count 中相应字符出现的次数
            这个时候 count 中的字符的个数都 小于等于 need
            开始移动 left，并且将 left 对应的字符的个数加一
            """
            ans = min(ans, right - left)
            if ans == 0:
                break
            count[ord(s[left])] += 1
            left += 1
        return ans

print(Solution().balancedString("QWQRREQR"))